package com.zwh.se.io;


import com.zwh.tool.utils.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;

/**
 * @author yexi
 * File是文件和文件夹（目录）的抽象，用于表示磁盘中某个文件或文件夹。
 * 什么是文件：为了便于数据的管理和检索而引入的概念。一篇文章、一段视频、一个可执行程序,都可以被保存为一个文件,并赋予一个文件名。
 * 操作系统以文件为单位管理磁盘中的数据。文件可以按功能分为各类文件:文本文件、音频文件等。但从数据存储的本质上看,
 * 所有的文件本质上都是一样的,都是由一个个字节组成的,归根到底都是 0、1 比特串。
 * 只是一些功能文件要通过相对应的软件或硬件去读取时才算是被正确的使用,为此文件引入了"后缀名"这个概念。操作系统通过
 * 文件的后缀名判断该文件属于哪一类文件后,即可去调用相对应的软件或硬件去处理。
 * 什么是文件夹(目录)：成千上万的文件不加以分类使用就会不方便,故而引入的被称为"树形目录"的机制。可以把文件放在不同的文件夹中,
 * 并且文件夹中还可以嵌套文件夹,便于用户对文件进行管理和使用。（注意：不同操作系统对文件夹的实现底层可能并不一样）
 * 该类包含了文件的创建、删除、重命名、判断是否存在等方法。
 * 只能设置和获取文件本身的信息（文件大小，是否可读），不能设置和获取文件里面的内容。
 * 分隔符：
 * Unix: 严格区分大小写，使用"/"来表示路径分隔符。
 * Windows: 默认情况下是不区分大小写的，使用”\”来分割目录路径。但是在Java中一个”\”表示转义，所以在Windows系统中就得使用两个”\\”。
 * <p>
 * 本demo测试文件的创建与试用file对象的各种方法
 * <p>
 * TIPS:对象本质上也是容器
 * TIPS:抽象路径，偶尔会在源码或者网上资料看到的概念，其实并非特指某种路径，而是java的程序逻辑编程概念，以抽象路径代表不同系统下的路径，写程序可以不用理会
 * TIPS:"/"代表着根目录，"./"代表当前目录，"../"代表上级目录
 */
public class FileDemo {

    public static void main(String[] args) throws Exception {
        //TIPS:即便该文件实际上还没有被创建，但很多信息其实就已经可以获取到了(记住,File只是一个封装)
        // 提供路径给file对象,这里分隔符用多种方式来展示,扩大学习面
        System.out.println("----------查看传入不同路径获取的效果----------");
        File file = new File("/");
        FileUtils.printPaths(file);
        file = new File(File.separator + "test/user\\test.txt");
        FileUtils.printPaths(file);
        file = new File("/Users/yexi2022/../yexi2022/test.txt");
        FileUtils.printPaths(file);
        //空的抽象路径名(empty abstract pathname)
        file = new File("test.txt");
        FileUtils.printPaths(file);
        file = new File(new URI("file:///Users/yexi2022/test.txt"));
        FileUtils.printPaths(file);
        System.out.println("----------其他获取方法----------");
        // String getName()：获取文件名称
        System.out.println(file.getName());
        // File getParentFile()：获取上级目录文件(获取不到返回就是null)
        System.out.println(file.getParentFile() == null ? "不存在" : file.getParentFile().getName());
        // boolean exists()：判断文件是否存在
        System.out.println(file.exists());
        // boolean isFile() ：判断是否是文件，只有实际存在的情况下才能判断，否则false
        System.out.println(file.isFile());
        // boolean isDirectory()：判断是否是目录，只有实际存在的情况下才能判断，否则false
        System.out.println(file.isDirectory());
        // boolean canRead()：判断文件是否可读，只有实际存在的情况下才能判断，否则false
        System.out.println(file.canRead());
        // boolean canWrite()：判断文件是否可写，只有实际存在的情况下才能判断，否则false
        System.out.println(file.canWrite());
        // String getParent()：获取上级目录
        System.out.println(file.getParent());
        // boolean isHidden()：判断文件是否隐藏
        System.out.println(file.isHidden());
        // long length()：判断文件的大小
        System.out.println(file.length());
        // return getPath()：返回相对路径
        System.out.println(file.toString());
        System.out.println("----------创建方法----------");
        if (file.getName().contains(".")) {
            try {
                System.out.println("文件创建结果: " + file.createNewFile());
            } catch (IOException e) {
                //异常原因是因为上级目录不存在，要先创建上级目录才能创建文件
                System.out.println("\033[31;4m" + e + "\033[0m");
                //如果当前文件的父文件夹不存在,则创建
                if (!file.getParentFile().exists()) {
                    //boolean mkdirs()：创建当前目录和上级目录
                    System.out.println("文件夹创建结果: " + file.getParentFile().mkdirs());
                    // boolean createNewFile():当且仅当不存在具有此路径名指定名称的文件时，不可分地创建一个新的空文件。
                    System.out.println("文件创建结果: " + file.createNewFile());
                }
            }
        } else {
            // boolean mkdir 作为文件夹来创建。只能创建单层目录，＋s的则是一次性创建多层目录
            System.out.println("文件夹创建结果: " + file.mkdir());
        }
        System.out.println("----------列出给定目录下所有文件信息----------");
        // list():展示提供的目录对象下的所有文件/目录的名字(如果提供的是文件而非目录则返回null)
        if (file.getName().contains(".")) {
            String[] list = file.getParentFile().list();
            System.out.println(Arrays.toString(list));
        } else {
            String[] list = file.list();
            System.out.println(Arrays.toString(list));
        }
        // File[] listFiles() ：列出给定目录下所有文件/目录对象(如果提供的是文件而非目录则返回null)
        // 由于返回的不仅仅是名字,所以该方法可以使用的范围更加广泛,比如借由File对象可以一层层往下遍历获取到所有的文件
        File[] fs = file.listFiles();
        if (fs != null) {
            for (File f : fs) {
                System.out.println(f.getName());
            }
        } else {
            for (File listFile : file.getParentFile().listFiles()) {
                System.out.println(listFile.getName());
            }
        }
        System.out.println("----------删除方法----------");
        //boolean delete() ：删除文件(如果删除的是目录的话,只会删除一层。并且前提是该目录是空的,如果有内容就不会被删除。
        System.out.println("删除结果: " + file.getParentFile().delete());
        System.out.println("删除结果: " + file.delete());
        System.out.println("删除结果: " + file.getParentFile().delete());
    }
}